<?php
/**
 * This file is part of HelloWorld
 *
 */
namespace common\helpers;

use common\models\AreaModel;
use Yii;
use yii\helpers\BaseInflector;
use yii\web\Response;

class CommonHelper
{
    /**
     * 返回固定格式.
     *
     * @param mixed $code
     * @param string $msg
     * @param array $data
     * @param mixed $object
     *
     * @return array
     */
    public static function toResult($code = 0, $msg = '成功', $data = [], $object = false)
    {
        if (is_array($code)) {
            $result = $code + [
                'code' => 0,
                'msg' => $msg ? $msg : (! empty($code['code']) ? '失败' : '成功'),
                'data' => $data,
            ];
        } else {
            $result = [
                'code' => $code,
                'msg' => $msg ? $msg : ($code ? '失败' : '成功'),
                'data' => $data,
            ];
        }

        if (empty($result['data'])) {
            $result['data'] = $object ? ( new \stdClass() ) : [];
        }

        return $result;
    }

    /**
     * 返回json数据.
     * @param mixed $code
     * @param string $msg
     * @param array $data
     * @param bool $object data格式
     * @param mixed $log
     * @param bool $replaceMsgFlag 替换错误提示
     * @param bool $isEncrypt 返回数据是否需要加密
     */
    public static function toJson($code = 0, $msg = '成功', $data = [], $object = false, $log = false, $replaceMsgFlag = true, $isEncrypt = false)
    {
        $result = static::toResult($code, $msg, $data, $object);

        if (Yii::$app->id == 'app-backend' && isset(Yii::$app->params['errorCode'][$result['code']])) {
            $result['msg'] = Yii::$app->params['errorCode'][$result['code']];
        }

        if ($log) {
            if (Yii::$app->request->isPost) {
                $request = ['_POST' => Yii::$app->request->post(), '_FILES' => $_FILES];
                $sensitiveFields = ['pay_password', 'origin_pay_password', 'origin_password', 'sms_code', 'password', 'confirm_password'];
                foreach ($sensitiveFields as $field) {
                    if (! empty($request['_POST'][$field])) {
                        $request['_POST'][$field] = '******';
                    }
                }
            } else {
                $request = Yii::$app->request->get();
            }
            $log = [
                'method' => Yii::$app->request->method,
                'request' => $request,
                'response' => $result,
                'header' => [
                    'ip' => CommonHelper::getUserIP(),
                    'version' => Yii::$app->request->getHeaders()->get('version'),
                    'device' => Yii::$app->request->getHeaders()->get('device'),
                    'channel' => Yii::$app->request->getHeaders()->get('channel'),
                    'agent' => $_SERVER['HTTP_USER_AGENT'] ?? null,
                    'tokentype' => Yii::$app->request->getHeaders()->get('tokenType'),
                    'OPENID' => Yii::$app->request->getHeaders()->get('OPENID')
                        ? substr(Yii::$app->request->getHeaders()->get('OPENID'), 0, -6) . '******' : null,
                    'appChannel' => Yii::$app->request->getHeaders()->get('appChannel', 'DST'),
                    'deviceModel' => Yii::$app->request->getHeaders()->get('deviceModel'),
                    'token' => Yii::$app->request->getHeaders()->get('token'),
                ],
            ];
            if (!YII_ENV_PROD) {
                Yii::info(Yii::$app->request->getHeaders()->toArray());
            }
            if (is_object($result['data'])) {
                $log['response']['data'] = json_encode($log['response']['data'], JSON_UNESCAPED_UNICODE);
            }

            Yii::info(json_encode($log, JSON_UNESCAPED_UNICODE));
        }
        if ($replaceMsgFlag) {
            if ($result['code'] && !empty($result['msg']) && (mb_strlen($result['msg']) > 50
                    || strpos($result['msg'], 'SQLSTATE') !== false || !preg_match('/[\x7f-\xff]/', $result['msg']))) {
                $result['msg'] = '操作失败';
            }
        }
        $response = Yii::$app->response;
        $response->headers->add('timestamp', time());
        if ($isEncrypt && Yii::$app->get('serviceEncryptClientDecryptRsa')) {
            $response->headers->set('Content-type', 'text/plain;charset=utf-8');
            $response->format = Response::FORMAT_RAW;
            # 加密
            $result = Yii::$app->serviceEncryptClientDecryptRsa->privateEncrypt($result);
        } else {
            $response->headers->set('Content-type', 'application/json;charset=utf-8');
            $response->format = Response::FORMAT_JSON;
        }
        $response->data = $result;
        $response->send();
        exit;
    }

    /**
     * 判断是否为json.
     * @param $data
     * @return bool
     */
    public static function isJson($data)
    {
        if (! is_string($data)) {
            return false;
        }

        return is_object(json_decode($data));
    }

    /**
     * curl请求
     * @param $url
     * @param array $params 请求参数
     * @param array $header http头
     * @param string $method p POST, g GET
     * @param bool $log
     * @return mixed
     */
    public static function doCurlRequest($url, $params = [], $header = [], $method = 'p', $log = true)
    {
        if (! function_exists('curl_init')) {
            exit('Need to open the curl extension');
        }
        $method = in_array($method, ['g', 'G', 'get', 'GET']) ? 'g' : 'p';
        if ($method == 'g' && $params) {
            if (strpos($url, '?')) {
                $url .= '&' . http_build_query($params);
            } else {
                $url .= '?' . http_build_query($params);
            }
        }

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        curl_setopt($ch, CURLOPT_HEADER, 0); //展示响应头
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); //设置连接等待时间,0不等待
        curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
        if ($method == 'p') {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
            if (static::isJson($params)) {
                $header[] = 'Content-Type: application/json';
                $header[] = 'charset:UTF-8';
                $header[] = 'Content-Length: ' . strlen($params);
            }
        }
        $header && curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

        $output = curl_exec($ch);

        if ($log) {
            Yii::info(
                'Method:' . $method
                . ' URL:' . urldecode($url)
                . ' Header:' . (is_array($header) ? json_encode($header, JSON_UNESCAPED_UNICODE) : $header)
                . ' Request:' . (is_array($params) ? json_encode($params, JSON_UNESCAPED_UNICODE) : $params)
                . ' Response:' . (is_array($output) ? json_encode($output, JSON_UNESCAPED_UNICODE) : $output)
            , 'curl');
        }

        if ($output === false) {
            return curl_error($ch);
        }
        curl_close($ch);
        return $output;
    }

    /**
     * @参数
     * @name 生成随机数
     * @param mixed $type
     * @param mixed $len
     */
    public static function randomString($type = 'alnum', $len = 8)
    {
        static $storage = [];

        switch ($type) {
            case 'basic':
                $string = mt_rand();
                break;
            case 'alnum':
            case 'lalnum':
            case 'numeric':
            case 'nozero':
            case 'alpha':
                switch ($type) {
                    case 'alpha':
                        $pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
                        break;
                    case 'alnum':
                        $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
                        break;
                    case 'lalnum':
                        $pool = '0123456789abcdefghijklmnopqrstuvwxyz';
                        break;
                    case 'numeric':
                        $pool = '0123456789';
                        break;
                    case 'nozero':
                        $pool = '123456789';
                        break;
                }
                $string = substr(str_shuffle(str_repeat($pool, ceil($len / strlen($pool)))), 0, $len);
                break;
            case 'unique':
            case 'md5':
                $string = md5(uniqid(mt_rand()));
                break;
            case 'encrypt':
            case 'sha1':
                $string = sha1(uniqid(mt_rand(), true));
                break;
            case 'inviteCode':
                $pool = '0123456789abcdefghjklmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';
                $string = substr(str_shuffle(str_repeat($pool, ceil($len / strlen($pool)))), 0, $len);
                break;
            case 'pwd':
                $pool = 'abcdefghijklmnopqrstuvwxyz';
                $string = $pool[mt_rand(0,25)];
                $pool = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
                $string .= $pool[mt_rand(0,25)];
                $pool = '1234567890';
                $string .= $pool[mt_rand(0,9)];
                $pool = '~!@#$%^&*.?,;\'-+';
                $string .= $pool[mt_rand(0,15)];
                $pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890~!@#$%^&*.?,;\'-+';
                $len -= 4;
                $string .= substr(str_shuffle(str_repeat($pool, ceil($len / strlen($pool)))), 0, $len);
                $string = str_shuffle($string);
        }
        if (isset($storage[$string])) {
            return static::randomString($type, $len);
        }
        $storage[$string] = 1;
        if (count($storage) > 10000) {
            array_shift($storage);
        }

        return $string;
    }

    /**
     * 加密函数.
     *
     * @param string $txt 需要加密的字符串
     * @param string $key 密钥
     * @param mixed $string
     * @return string 返回加密结果
     */
    public static function encrypt($string, $key = '')
    {
        $key || $key = Yii::$app->request->cookieValidationKey;
        $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.';
        $ikey = 'vxGx2BkOm0qIr9s36-Rgp6Z.r6ogZm_W';
        $nh1 = rand(0, 64);
        $nh2 = rand(0, 64);
        $nh3 = rand(0, 64);
        $ch1 = $chars[$nh1];
        $ch2 = $chars[$nh2];
        $ch3 = $chars[$nh3];
        $nhnum = $nh1 + $nh2 + $nh3;
        $knum = 0;
        $i = 0;
        while (isset($key[$i])) {
            $knum += ord($key[$i++]);
        }
        $mdKey = substr(md5(md5(md5($key . $ch1) . $ch2 . $ikey) . $ch3), $nhnum % 8, $knum % 8 + 16);
        $string = base64_encode(time() . '_' . $string);
        $string = str_replace(['+', '/', '='], ['-', '_', '.'], $string);
        $tmp = '';
        $j = 0;
        $k = 0;
        $tlen = strlen($string);
        $klen = strlen($mdKey);
        for ($i = 0; $i < $tlen; ++$i) {
            $k = ($k == $klen) ? 0 : $k;
            $j = ($nhnum + strpos($chars, $string[$i]) + ord($mdKey[$k++])) % 64;
            $tmp .= $chars[$j];
        }
        $tmplen = strlen($tmp);
        $tmp = substr_replace($tmp, $ch3, $nh2 % ++$tmplen, 0);
        $tmp = substr_replace($tmp, $ch2, $nh1 % ++$tmplen, 0);
        return substr_replace($tmp, $ch1, $knum % ++$tmplen, 0);
    }

    /**
     * 解密函数.
     *
     * @param string $txt 需要解密的字符串
     * @param string $key 密匙
     * @param mixed $string
     * @param mixed $ttl
     * @return string 字符串类型的返回结果
     */
    public static function decrypt($string, $key = '', $ttl = 0)
    {
        $key || $key = Yii::$app->request->cookieValidationKey;
        $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.';
        $ikey = 'vxGx2BkOm0qIr9s36-Rgp6Z.r6ogZm_W';
        $knum = 0;
        $i = 0;
        $tlen = strlen($string);
        while (isset($key[$i])) {
            $knum += ord($key[$i++]);
        }
        $ch1 = $string[$knum % $tlen];
        $nh1 = strpos($chars, $ch1);
        $string = substr_replace($string, '', $knum % $tlen--, 1);
        $ch2 = $string[$nh1 % $tlen];
        $nh2 = strpos($chars, $ch2);
        $string = substr_replace($string, '', $nh1 % $tlen--, 1);
        $ch3 = $string[$nh2 % $tlen];
        $nh3 = strpos($chars, $ch3);
        $string = substr_replace($string, '', $nh2 % $tlen--, 1);
        $nhnum = $nh1 + $nh2 + $nh3;
        $mdKey = substr(md5(md5(md5($key . $ch1) . $ch2 . $ikey) . $ch3), $nhnum % 8, $knum % 8 + 16);
        $tmp = '';
        $j = 0;
        $k = 0;
        $tlen = strlen($string);
        $klen = strlen($mdKey);
        for ($i = 0; $i < $tlen; ++$i) {
            $k = ($k == $klen) ? 0 : $k;
            $j = strpos($chars, $string[$i]) - $nhnum - ord($mdKey[$k++]);
            while ($j < 0) {
                $j += 64;
            }
            $tmp .= $chars[$j];
        }
        $tmp = str_replace(['-', '_', '.'], ['+', '/', '='], $tmp);
        $tmp = trim(base64_decode($tmp));

        if (preg_match('/\\d{10}_/s', substr($tmp, 0, 11))) {
            if ($ttl > 0 && (time() - substr($tmp, 0, 10) > $ttl)) {
                $tmp = null;
            } else {
                $tmp = substr($tmp, 11);
            }
        }

        return $tmp;
    }

    /**
     * 空判断.
     * @param $value
     * @return bool
     */
    public static function isEmpty($value)
    {
        return $value === '' || $value === [] || $value === null || is_string($value) && trim($value) === '';
    }

    /**
     * 去除.
     * @param bool $keepKeys
     * @return array
     */
    public static function removeZero(array $array = [], $keepKeys = true)
    {
        if ($keepKeys) {
            foreach ($array as $k => $v) {
                if (bccomp($v['value'], 0, 2) == 0) {
                    unset($array[$k]);
                }
            }
            return $array;
        }

        $result = [];
        foreach ($array as $v) {
            if (bccomp($v['value'], 0, 2) != 0) {
                $result[] = $v;
            }
        }

        return $result;
    }

    /**
     * 过滤掉emoji表情.
     * @param $str
     * @return null|array|string|string[]
     */
    public static function filterEmoji($str)
    {
        if (is_array($str)) {
            foreach ($str as $key => $val) {
                $str[$key] = static::filterEmoji($val);
            }
        } else {
            $str = preg_replace_callback(
                '/./u',
                function (array $match) {
                    return strlen($match[0]) >= 4 ? '' : $match[0];
                },
                $str
            );
        }
        return $str;
    }


    /**
     * 处理手机号.
     * @param $mobile
     * @return array
     */
    public static function handleMobile($mobile)
    {
        if (is_array($mobile)) {
            foreach ($mobile as $key => $value) {
                // $mobile[$key]['mobile'] = substr_replace($value['mobile'], '****', 3, 4);
                $mobile[$key]['bind_time'] = date('Y/m/d H:i', strtotime($value['bind_time']));
            }
            return $mobile;
        }
        //return substr_replace($mobile, '****', 3, 4);
        return $mobile;
    }

    /**
     * 处理手机号(脱敏).
     * @param $mobile
     * @return array
     */
    public static function handleHideMobile($mobile)
    {
        if (is_array($mobile)) {
            foreach ($mobile as $key => $value) {
                $mobile[$key]['mobile'] = substr_replace($value['mobile'], '****', 3, 4);
                $mobile[$key]['bind_time'] = date('Y-m-d', strtotime($value['bind_time']));
            }
            return $mobile;
        }
        //return substr_replace($mobile, '****', 3, 4);
        return $mobile;
    }

    public static function strReplace($string, $start, $end)
    {
        //参数一:$string 需要替换的字符串
        //参数二:$start 开始的保留几位
        //参数三:$end 最后保留几位
        $strlen = mb_strlen($string, 'UTF-8'); //获取字符串长度
        $firstStr = mb_substr($string, 0, $start, 'UTF-8'); //获取第一位
        $lastStr = mb_substr($string, -$end, $end, 'UTF-8'); //获取最后一位

        return $strlen == 2 ? $firstStr . str_repeat('*', mb_strlen($string, 'utf-8') - 1) : $firstStr . str_repeat('*', $strlen - $start - $end) . $lastStr;
    }

    /**
     * 刷新config uniqid.
     */
    public static function refreshConfigUniqid()
    {
        if (! empty(Yii::$app->params['uniqid'])) {
            $uniqid = Yii::$app->params['uniqid'];
            if (is_callable($uniqid)) {
                call_user_func($uniqid, true);
            } else {
                Yii::$app->params['uniqid'] = str_replace('.', '', uniqid('', true));
            }
        }
    }

    /**
     * 生成订单号.
     * @return string
     */
    public static function createOrderNo()
    {
        static $_microtime = 0;
        static $_worker_id = 0;

        if (! $_microtime) {
            [$usec, $sec] = explode(' ', microtime());
            $_microtime = bcadd($sec, $usec, 4);
            $_worker_id = mt_rand(0, 9);
            $pos = strpos($usec, '.');
            $usec = $pos ? substr($usec, $pos + 1, 4) : $usec;
        }

        if (! isset($usec)) {
            $arr = explode('.', $_microtime);
            $sec = $arr[0];
            $usec = $arr[1] ?? '0';
        }
        $usec = str_pad($usec, 4, '0');

        $order_no = date('YmdHis', $sec) . $_worker_id . $usec;
        $_microtime = bcadd($_microtime, 0.0001, 4);

        return $order_no;
    }

    /***
     * 生成字符串
     * @return string
     */
    public static function generateString($length = 30)
    {
        [$msec, $sec] = explode(' ', microtime());
        $pos = strpos($msec, '.');
        $msec = $pos ? substr($msec, $pos + 1, 3) : $msec;
        $msec = str_pad($msec, 3, '0', STR_PAD_RIGHT);
        $datetime = date('YmdHis', $sec) . $msec;
        $curLen = strlen($datetime);

        if ($length <= $curLen) {
            return $datetime;
        }

        $length = $length - $curLen;
        if (function_exists('random_bytes')) {
            $bytes = random_bytes(ceil($length / 2));
            $uuid = substr(bin2hex($bytes), 0, $length);
        } elseif (function_exists('openssl_random_pseudo_bytes')) {
            $bytes = openssl_random_pseudo_bytes(ceil($length / 2));
            $uuid = substr(bin2hex($bytes), 0, $length);
        } else {
            $pool = '0123456789abcdefghijklmnopqrstuvwxyz';
            $uuid = substr(str_shuffle(str_repeat($pool, ceil($length / strlen($pool)))), 0, $length);
        }

        return $datetime . $uuid;
    }

    public static function isIE()
    {
        if (empty($_SERVER['HTTP_USER_AGENT'])) {
            return false;
        }
        $userAgent = htmlentities($_SERVER['HTTP_USER_AGENT'], ENT_QUOTES, 'UTF-8');
        if (preg_match('~MSIE|Internet Explorer~i', $userAgent)
            || (strpos($userAgent, 'Trident/7.0') !== false && strpos($userAgent, 'rv:11.0') !== false)) {
            return true;
        }

        return false;
    }

    /**
     * 生成.
     * @param $str
     * @param $filename
     */
    public static function csv(string $filename, string $str): void
    {
        $filename = urlencode($filename);
        $filename = str_replace('+', '%20', $filename);
        //$filename = mb_convert_encoding( $filename, 'GBK', 'UTF-8' );
        $str = mb_convert_encoding($str, 'GBK', 'UTF-8');

        header('Content-type: application/octet-stream');
        header('Content-Type:application/csv;charset=GBK');
        header('Content-Description: File Transfer');
        if (static::isIE()) {
            header('Content-Disposition: attachment; filename=' . $filename);
        } else {
            header('Content-Disposition: attachment; filename=' . $filename . ';filename*=UTF-8\'' . $filename . '\'');
        }
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . strlen($str));

        exit($str);
    }

    /**
     * 解析unicode.
     * @param $str
     * @return null|string|string[]
     */
    public static function decodeUnicode($str)
    {
        return preg_replace_callback(
            '/\\\\u([0-9a-f]{4})/i',
            function ($matches) {
                return mb_convert_encoding(pack('H*', $matches[1]), 'UTF-8', 'UCS-2BE');
            },
            $str
        );

        return $str;
    }

    /**
     * arrayFilterRecursive 清除多维数组里面的空值
     * @param array $array
     * @return array
     * @DateTime 2018/12/3  11:27
     */
    public static function arrayFilterRecursive(array &$arr)
    {
        if (count($arr) < 1) {
            return [];
        }
        foreach ($arr as $k => $v) {
            if (is_array($v)) {
                $arr[$k] = static::arrayFilterRecursive($v);
            }
            if (is_null($arr[$k]) && $arr[$k] == '') {
                unset($arr[$k]);
            }
        }
        return $arr;
    }

    /**
     * cpcnFilter 清除中金特殊字符
     * @param array $array
     * @param mixed $data
     * @return array
     * @DateTime 2018/12/3  11:27
     */
    public static function cpcnFilter($data)
    {
        $search = ['&', '%', '/'];
        $replace = ['', '', ''];
        if (is_array($data)) {
            foreach ($data as $k => $v) {
                if (is_array($v)) {
                    $data[$k] = static::cpcnFilter($v);
                } else {
                    $data[$k] = str_replace($search, $replace, $v);
                }
            }

            return $data;
        }

        $data = str_replace($search, $replace, $data);

        return $data;
    }

    /**
     * 获取用户IP
     * @return null|string
     */
    public static function getUserIP()
    {
        if (! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            return explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0];
        }
        if (! empty($_SERVER['HTTP_CLIENT_IP'])) {
            return $_SERVER['HTTP_CLIENT_IP'];
        }

        if ( class_exists( 'yii\web\Request' ) && Yii::$app->request->hasMethod( 'getUserIP' ) ) {
            return Yii::$app->request->getUserIP();
        }

        return '0.0.0.0';
    }

    /**
     * 获取base64图片
     * @param $imgFile 图片
     * @param $ext 后缀
     * @return string
     */
    public static function getImageBase64($imgFile, $ext = '')
    {
        $imgBase64 = '';
        if (file_exists($imgFile)) {

            $appImgFile = $imgFile; // 图片路径
            $imgInfo    = getimagesize($appImgFile); // 取得图片的大小，类型等
            $fp         = fopen($appImgFile, "r"); // 图片是否可读权限

            if ($fp) {
                $filesize    = filesize($appImgFile);
                $fileContent = fread($fp, $filesize);
                $fileContent = base64_encode($fileContent); // base64编码
                //$fileContent = chunk_split( $fileContent ); // base64编码

                if (!$ext) {
                    switch ($imgInfo[2]) {           //判读图片类型

                        case 1:
                            $ext = "gif";
                            break;

                        case 2:
                            $ext = "jpg";
                            break;

                        case 3:
                            $ext = "png";
                            break;

                        default:
                            $ext = "jpg";
                            break;

                    }
                }
                $imgBase64 = 'data:image/' . $ext . ';base64,' . $fileContent;//合成图片的base64编码
            }
            fclose($fp);
        } else {
            $fileContent = @file_get_contents($imgFile);
            $fileContent = base64_encode($fileContent);
            if (false === $fileContent) {
                $fileContent = '';
            }
            //$fileContent = chunk_split( $fileContent ); // base64编码
            if (strpos($fileContent, 'data:image') !== 0) {
                if (!$ext) {
                    $path = parse_url($imgFile, PHP_URL_PATH);
                    $ext = pathinfo($path, PATHINFO_EXTENSION);
                }

                $imgBase64 = 'data:image/' . $ext . ';base64,' . $fileContent;//合成图片的base64编码
            }
        }

        return $imgBase64; //返回图片的base64
    }

    /**
     * 获取用户的出生日期
     * @param $IDCard
     * @return mixed
     */
    public static function getBirthInfoFromIdCard($IDCard)
    {
        $result['age']      = 0;
        $result['birthday'] = '';
        $result['sex']      = 0;
        if (!preg_match("/^[1-9]([0-9a-zA-Z]{17}|[0-9a-zA-Z]{14})$/i", $IDCard)) {
            return $result;
        }
        if (strlen($IDCard) == 18) {
            $tyear         = intval(substr($IDCard, 6, 4));
            $tmonth        = intval(substr($IDCard, 10, 2));
            $tday          = intval(substr($IDCard, 12, 2));
            $result['sex'] = intval(substr($IDCard, 16, 1)) % 2 == 1 ? 1 : 2;
        } elseif (strlen($IDCard) == 15) {
            $tyear         = intval("19" . substr($IDCard, 6, 2));
            $tmonth        = intval(substr($IDCard, 8, 2));
            $tday          = intval(substr($IDCard, 10, 2));
            $result['sex'] = intval(substr($IDCard, 14, 1)) % 2 == 1 ? 1 : 2;
        }
        if ($tyear > date("Y") || $tyear < (date("Y") - 100)) {
            return $result;
        } elseif ($tmonth < 0 || $tmonth > 12) {
            return $result;
        } elseif ($tday < 0 || $tday > 31) {
            return $result;
        } else {
            $tdate              = date("Y-m-d", strtotime($tyear . "-" . $tmonth . "-" . $tday));
            $d                  = time() - mktime(0, 0, 0, $tmonth, $tday, $tyear);
            $result['age']      = floor($d / (365 * 86400));
            $result['birthday'] = $tdate;//生日日期
        }
        return $result;
    }

    /** 毫秒时间戳
     * @return float
     */
    public static function getMillisecond()
    {
        list($s1, $s2) = explode(' ', microtime());
        return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
    }

    /**  秒转天时分
     * @param $second
     * @return string
     */
    public static function transferSecond($second){
        if($second == 0) return  '0秒';
        $d = floor($second / (3600*24));
        $h = floor(($second % (3600*24)) / 3600);
        $m = floor((($second % (3600*24)) % 3600) / 60);
        $s = floor((($second % (3600*24)) % 3600)  % 60);
        if($d>'0'){
            $desc = $d.'天'.$h.'小时'.$m.'分'.$s."秒";
        }else{
            if($h!='0'){
                $desc = $h.'小时'.$m.'分'.$s."秒";
            }elseif($m!='0'){
                $desc = $m.'分'.$s."秒";
            }else{
                $desc = $s."秒";
            }
        }
        return $desc;
    }

    /**
     * 获取显示地址
     * @param $url
     * @return string
     */
    public static function getDisplayUrl($url)
    {
        if ($url) {
            return $url;
        }
        return Yii::$app->id == 'app-backend' ? \yii\helpers\Url::to('@web/images/nopic.jpg', true) : '';
    }

    /**
     * 解析结束时间
     * @param string $dateString
     */
    public static function parseIdcardEffectiveDate(string $dateString, $glue = '-')
    {
        $idCardDate = [
            'startDate'=>'',
            'endDate'=>'',
        ];
        $dateString = trim($dateString);
        $dateString = trim($dateString, '-');
        $dateString = trim($dateString);
        if (!$dateString) {
            return $idCardDate;
        }

        $startString = '';
        if (mb_strlen($dateString) > 10) {
            $dateArr = explode('-', $dateString);
            $endString = $dateArr[1] ?? $dateArr[0];
            $startString  = $dateArr[0] ?? '';
        } elseif ($dateString == '长期') {
            $endString = '9999' . $glue . '12' . $glue . '31';
        } else {
            $endString = $dateString;
        }

        if($startString){
            $startString = trim($startString);
            $startString = str_replace(['.', '/'], ['-', '-'], $startString);
            if($glue){
                $dateArr = date_parse($startString);
                $startString = $dateArr['year'] . $glue . str_pad($dateArr['month'], 2, '0', STR_PAD_LEFT)
                    . $glue . str_pad($dateArr['day'], 2, '0', STR_PAD_LEFT);
            }
            $idCardDate['startDate'] = $startString;
        }

        $endString = trim($endString);
        $endString = str_replace(['.', '/'], ['-', '-'], $endString);
        if ($glue) {
            if ($endString == '长期') {
                $endString = '9999' . $glue . '12' . $glue . '31';
            } else {
                $dateArr = date_parse($endString);
                $endString = $dateArr['year'] . $glue . str_pad($dateArr['month'], 2, '0', STR_PAD_LEFT)
                    . $glue . str_pad($dateArr['day'], 2, '0', STR_PAD_LEFT);
            }
        }

        $idCardDate['endDate'] = $endString;

        if ($idCardDate['startDate'] && $idCardDate['startDate'] != '长期') {
            $time = strtotime($idCardDate['startDate']);
            if($idCardDate['startDate'] != date('Y-m-d', $time)){
                $idCardDate['startDate'] = '';
            }
        }
        if ($idCardDate['endDate'] && $idCardDate['endDate'] != '长期') {
            $time = strtotime($idCardDate['endDate']);
            if($idCardDate['endDate'] != date('Y-m-d', $time)){
                $idCardDate['endDate'] = '';
            }
        }

        return $idCardDate;
    }

    /**
     * 解析开始时间
     * @param string $dateString
     */
    public static function parseIdcardEffectiveDateStart(string $dateString, $glue = '-')
    {
        $dateString = trim($dateString);
        $dateString = trim($dateString, '-');
        $dateString = trim($dateString);
        if (!$dateString) {
            return '';
        }

        if (mb_strlen($dateString) > 10) {
            $dateArr = explode('-', $dateString);
            $startString = $dateArr[0] ?? '';
        } elseif ($dateString == '长期') {
            $startString = date('Y' . $glue . 'm' . $glue . 'd');
        } else {
            return '';
        }

        if (!$startString) {
            return date('Y' . $glue . 'm' . $glue . 'd');
        }

        $startString = trim($startString);
        $startString = str_replace(['.', '/'], ['-', '-'], $startString);
        if ($glue) {
            $dateArr = date_parse($startString);
            $startString = $dateArr['year'] . $glue . str_pad($dateArr['month'], 2, '0', STR_PAD_LEFT)
                . $glue . str_pad($dateArr['day'], 2, '0', STR_PAD_LEFT);
        }

        return $startString;
    }

    /**
     * 哈希文件
     * @param $filename
     * @return string
     */
    public static function hashHmacFile($filename)
    {
        return hash_hmac_file( 'sha1', $filename, 'PMXg9FxP9MaWki8e' );
    }

    /** 处理select
     * @param $data
     * @return array|string
     */
    public static function handleSelect(array $data,$toType = 'string')
    {
        if($toType == 'string'){
            $select = '';
            foreach ($data as $tablePrefix => $fieldList) {
                $handleField = array_map(function (&$field) use ($tablePrefix) {
                    return !is_numeric($tablePrefix) ? $tablePrefix . ".".$field : $field;
                }, $fieldList);
                $select .= join(',',$handleField).",";
            }
            return rtrim($select,',');
        }else{
            $handleField = [];
            foreach ($data as $tablePrefix => $fieldList) {
                array_map(function (&$field) use ($tablePrefix, &$handleField) {
                    $handleField[] = !is_numeric($tablePrefix) ? $tablePrefix . "." . $field : $field;
                }, $fieldList);
            }
            return $handleField;
        }
    }

    /**
     *  生成合同
     * @param string $p1 所属大区
     * @param string $p2 城市区号
     * @param string$p3 客户类群
     * @param string $p4 合同类型
     * @param string $p5 主合同日期
     * @param string $p6 合同流水号
     */
    public static function generateContractCode($p1, $p2, $p3, $p4, $p5, $p6 = '')
    {
        // 所属大区
        if (strlen($p1) >= 6) {
            // 根据城市新政代码获取所属大区
            $areaServeOrg = Yii::$app->dstOssGatewayApi->findAreaServeOrgByCityCode($p1)['data'];
            if ($areaServeOrg) {
                $areaServeOrg = array_shift($areaServeOrg);
                $p1 = empty($areaServeOrg['code']) ? 'QT' : $areaServeOrg['code'];
            } else {
                $p1 = 'QT';
            }
        }
        if (!$p1) {
            $p1 = 'QT';
        }

        // 城市区号
        if (strlen($p2) >= 6) {
            // 根据城市新政代码获取城市区号
            $area = AreaModel::getOne($p2, 2);
            if ($area) {
                $p2 = $area['area_code'];
            }
        }
        $p2 = substr($p2, -3);
        if (!$p2) {
            $p2 = '000';
        }

        // 客户类群
        if (!in_array($p3, ['B', 'C'])) {
            throw new \Exception('客户类群错误', 90136);
        }
        $p3 = strtoupper($p3);

        // 合同类型
        if (!in_array($p4, ['ZL', 'XS'])) {
            throw new \Exception('合同类型错误', 90137);
        }
        $p4 = strtoupper($p4);

        // 合同流水号
        if (!$p6) {
            $p6 = Yii::$app->cacheMapping->incrContractSerialNum();
        }
        if (!$p6) {
            throw new \Exception('合同流水号获取不到', 90138);
        }
        $p6 = ltrim($p6, '0');
        $p6 = str_pad($p6, 7, '0', STR_PAD_LEFT);
        $contractCode = "DSTA-{$p1}{$p2}{$p3}-{$p4}{$p5}-{$p6}";

        if (!YII_ENV_PROD) {
            $contractCode = strtoupper(substr(YII_ENV, 0, 1)). (substr(time(), -1, 1)) . $contractCode;
        }

        return $contractCode;
    }

    /**
     * 生成售车合同编号
     * @param string $p1 所属大区
     * @param string $p2 城市区号
     * @param string $p5 主合同日期
     * @param string$p3 客户类群
     * @param string $p6 合同流水号
     * @return string
     * @throws \Exception
     */
    public static function generateContractCodeForSaleCar($p1, $p2, $p5, $p3 = 'C', $p6 = '')
    {
        return static::generateContractCode($p1, $p2, $p3, $p4 = 'XS', $p5, $p6);
    }

    /**
     * 生成租车合同编号
     * @param string $p1 所属大区
     * @param string $p2 城市区号
     * @param string $p5 主合同日期
     * @param string$p3 客户类群
     * @param string $p6 合同流水号
     * @return string
     * @throws \Exception
     */
    public static function generateContractCodeForRentCar($p1, $p2, $p5, $p3 = 'C', $p6 = '')
    {
        return static::generateContractCode($p1, $p2, $p3, $p4 = 'ZL', $p5, $p6);
    }

    /**
     *  获取当月天数
     * @param $date
     * @return string
     */
    public static function getMonthDay( $date )
    {
        list($year,$month) = explode('-' , $date);       //切割日期  得到年份和月份
        if( in_array($month , array( '1' , '3' , '5' , '7' , '8' ,'01' , '03' , '05' , '07' , '08' , '10' , '12')))
        {
            $text = '31';
        }
        elseif( $month == 2 )
        {
            if ( $year%400 == 0  || ($year%4 == 0 && $year%100 !== 0) )        //判断是否是闰年
            {
                $text = '29';
            }
            else{
                $text = '28';
            }
        }
        else{
            $text = '30';
        }
        return $text;
    }

    /**
     * 获取月的第一天和最后一天
     * @param $curTime
     * @return array
     */
    public static function getMonthFirstAndLastDay($curTime)
    {
        $curTime = is_numeric($curTime) ? $curTime : strtotime($curTime);
        $firstDay = date('Y-m-01 H:i:s', $curTime);
        $lastDay = date('Y-m-'. date('t', $curTime) .' 23:59:59', $curTime);

        return [$firstDay, $lastDay];
    }

    /**
     * Converts array  a word like "send_email" to "sendEmail".
     * @param array $keys
     * @return array
     */
    public static function variablizeForKeys(array $keys)
    {
        foreach ($keys as &$key) {
            $key = BaseInflector::variablize($key);
        }

        return $keys;
    }

    /**
     * Converts array  a word like "send_email" to "sendEmail".
     * @param array $keys
     * @return array
     */
    public static function variablize(array $data)
    {
        $result = [];
        foreach ($data as $key => $val) {
            $key = BaseInflector::variablize($key);
            $result[$key] = $val;
        }

        return $result;
    }

    /**
     * 从二维数组里获取 $field = $fieldVal指定元素
     * @param array $list
     * @param string $field
     * @param $fieldVal
     * @param bool $retList
     * @return array|mixed
     */
    public static function getSpecificElementFromList(array $list, string $field, $fieldVal, bool $retList = false)
    {
        $result = [];
        if (!$list) {
            return $result;
        }

        foreach ($list as $item) {
            if ($item[$field] == $fieldVal) {
                if ($retList) {
                    $result[] = $item;
                } else {
                    $result = $item;
                    break;
                }
            }
        }

        return $result;
    }

    /**
     * 生成活动链接
     * @param $params
     */
    public static function formatCampaignUrl(string $url, array $params)
    {
        if (!array_key_exists('channel_origin', $params) || !array_key_exists('category', $params) || !array_key_exists('save_params', $params)) {
            return '';
        }
        if (is_array($params)) {
            $string = http_build_query($params);
        }
        return $url . '?' . $string;
    }

    /**
     * 手机号打星
     * @param $phone
     * @return string
     */
    public static function phoneStar($phone)
    {
        if (!$phone) {
            return '';
        }
        $phone = substr_replace($phone, '****', 3, -4);

        return $phone;
    }

    /**
     * 姓名打星
     * @param $phone
     * @return string
     */
    public static function realnameStar($realname)
    {
        $rnLen = mb_strlen($realname);
        if (!$rnLen) {
            return $realname;
        }

        if ($rnLen > 2) {
            $realname = mb_substr($realname, 0, 1) . str_repeat('*', $rnLen - 2) . mb_substr($realname, -1);
        } elseif ($rnLen) {
            $realname = mb_substr($realname, 0, 1) . '*';
        }

        return $realname;
    }

    /**
     * 打星
     * @param string $str
     * @param int $left
     * @param int $right
     * @return string
     */
    public static function stringStar($str, $left = 4, $right = 4)
    {
        if (!$str) {
            return '';
        }
        $strLen = mb_strlen($str);
        $brightLen = $left + $right;
        $starStr = str_repeat('*', $strLen < $brightLen ? 0 : ($strLen - $brightLen));
        $str = mb_substr($str, 0, $left) . $starStr . mb_substr($str, 0 - $right);

        return $str;
    }

    /**
     * 判断是否合法车牌号
     * @name isCarLicense
     * @author furong
     * @param $license
     * @return bool
     * @since 2016年12月24日 11:51:22
     * @abstract
     * 2017年4月7日 14:06:17 增加对 特种车牌，武警车牌,军牌的校验
     * 2018年3月5日 13:32:18 增加对 6位新能源车牌的校验
     */
    public static function isCarLicense($license)
    {
        if (empty($license)) {
            return false;
        }

        #匹配新能源车辆6位车牌
        #参考 https://baike.baidu.com/item/%E6%96%B0%E8%83%BD%E6%BA%90%E6%B1%BD%E8%BD%A6%E4%B8%93%E7%94%A8%E5%8F%B7%E7%89%8C
        {
            #小型新能源车
            $regular = "/[京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼川贵云渝藏陕甘青宁新]{1}[A-Z]{1}[DF]{1}[0-9a-zA-Z]{5}$/u";
            preg_match($regular, $license, $match);
            if (isset($match[0])) {
                return true;
            }
            #大型新能源车
            $regular = "/[京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼川贵云渝藏陕甘青宁新]{1}[A-Z]{1}[0-9a-zA-Z]{5}[DF]{1}$/u";
            preg_match($regular, $license, $match);
            if (isset($match[0])) {
                return true;
            }
        }

        #匹配民用车牌和使馆车牌
        # 判断标准
        # 1，第一位为汉字省份缩写
        # 2，第二位为大写字母城市编码
        # 3，后面是5位仅含字母和数字的组合
        {
            $regular = "/[京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼川贵云渝藏陕甘青宁新使]{1}[A-Z]{1}[0-9a-zA-Z]{5}$/u";
            preg_match($regular, $license, $match);
            if (isset($match[0])) {
                return true;
            }
        }

        #匹配特种车牌(挂,警,学,领,港,澳)
        #参考 https://wenku.baidu.com/view/4573909a964bcf84b9d57bc5.html
        {
            $regular = '/[京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼川贵云渝藏陕甘青宁新]{1}[A-Z]{1}[0-9a-zA-Z]{4}[挂警学领港澳]{1}$/u';
            preg_match($regular, $license, $match);
            if (isset($match[0])) {
                return true;
            }
        }

        #匹配武警车牌
        #参考 https://wenku.baidu.com/view/7fe0b333aaea998fcc220e48.html
        {
            $regular = '/^WJ[京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼川贵云渝藏陕甘青宁新]?[0-9a-zA-Z]{5}$/ui';
            preg_match($regular, $license, $match);
            if (isset($match[0])) {
                return true;
            }
        }

        #匹配军牌
        #参考 http://auto.sina.com.cn/service/2013-05-03/18111149551.shtml
        {
            $regular = "/[A-Z]{2}[0-9]{5}$/";
            preg_match($regular, $license, $match);
            if (isset($match[0])) {
                return true;
            }
        }

        return false;
    }

    /**
     * 数组元素转换成整数
     * @param $data
     * @param string $delimiter
     * @return array
     */
    public static function arrayMapIntval($data, $delimiter = ',')
    {
        if (!is_array($data)) {
            $data = explode($delimiter, $data);
        }

        return array_map('intval', $data);
    }

    /**
     * 主要缓存开关
     * @return bool
     */
    public static function mainCacheSwitch()
    {
        $open = Yii::$app->cacheMapping->getMainCacheSwitch();
        if (is_numeric($open)) {
            return $open ? true : false;
        }

        return Yii::$app->params['mainCacheSwitch'] ? true : false;
    }

    /**
     * 数据安全问题
     * @return bool
     */
    public static function unsetField(&$data, $tagId = 0)
    {
        if (!is_array($data)) {
            return false;
        }
        foreach ($data as $key => &$val) {
            if (isset($val['creatorId'])) {
                unset($val['creatorId']);
                unset($val['creatorName']);
                unset($val['modifierId']);
                unset($val['modifierName']);
            }
            if (is_array($val)) {
                self::unsetField($data[$key]);
            }
        }
        return $data;
    }

    /**
     * 获取注册来源数据（用户中心使用）
     * @param string $activityCode
     * @return mixed
     */
    public static function getRegisterSourceParams($activityCode = '')
    {
        $deviceOs = \Yii::$app->request->getHeaders()->get('device', '');
        if ($deviceOs) {
            if (stripos($deviceOs, 'android') !== false) {
                $source = 1;  //地上铁App
            } elseif (stripos($deviceOs, 'iOS') !== false) {
                $source = 1;  //地上铁App
            } elseif (stripos($deviceOs, 'h5wx') !== false) {
                $source = 2;  //h5
            } elseif (stripos($deviceOs, 'h5') !== false) {
                $source = 2;  //h5
            } elseif (stripos($deviceOs, 'wxmini') !== false) {
                $source = 14; //充电小程序
            } else {
                $source = 99; //其他
            }
        }
        $data['source']       = $source;
        $data['channelCode']  = \Yii::$app->request->getHeaders()->get('channel-code', '');
        $data['activityCode'] = is_null($activityCode) ? '' : $activityCode;
        return $data;
    }
    /**
     * 将字驼峰字符串转换成下划线,只转key
     * @param string $str
     * @since 210514
     */
    public static function toStringHumpUnderline($data)
    {
        if ($data === true) {
            return $data;
        }
        if (empty($data)) {
            return $data;
        }
        if (is_string($data)) {
            return $data;
        }
        if (is_object($data)) {
            $data = $data->toArray();
        }
        if (is_array($data)) {
            foreach ($data as $key => &$row) {
                if (is_object($row)) {
                    $row = $row->toArray();
                }
                if (is_array($row)) {
                    $row = self::toStringHumpUnderline($row);
                }
                #执行驼峰转换
                $datas[strtolower(preg_replace('/(?<=[a-z])([A-Z])/', '_$1', $key))] = $row;

                unset($row);
            }
            unset($data);
        }
        return $datas;
    }

    /**
     *加密数据
    */
    public static function aesEncrypt($key, $data )
    {
        // 是否为已加密字段
        if (empty($data)) {
            return '';
        }
        if (strstr($data, ":")) {
            return (string)$data;
        }

        $iv = substr( $key, 0, 5 );
        $iv = str_pad( $iv, 16, '0' );
        $encodedEncryptedData = base64_encode(openssl_encrypt( $data, 'aes-128-cbc',self::aesFixKey( $key ), OPENSSL_RAW_DATA, $iv ) );
        $encodedIV = base64_encode( $iv );
        return $encodedEncryptedData . ":" . $encodedIV;
    }
    /**
     *解密数据
    */
    public static function aesDecrypt($key, $data ):string
    {
        // 是否为已加密字段
        if (empty($data)){
            return '';
        }
        if (!strstr($data, ":")){
            return strval($data);
        }
        $parts = explode( ':', $data ); //Separate Encrypted data from iv.
        $encrypted = $parts[0];
        $iv = $parts[1];
        return (string)openssl_decrypt( base64_decode( $encrypted ), 'aes-128-cbc', self::aesFixKey( $key ), OPENSSL_RAW_DATA, base64_decode( $iv ) );
    }
    /**
     * key格式化
     * @param $key
     * @return false|mixed|string
     */
    public static function aesFixKey($key){

        if ( strlen( $key ) < 16 ) {
            //0 pad to len 16
            return str_pad( "$key", 16, "0" );
        }

        if ( strlen( $key ) > 16) {
            //truncate to 16 bytes
            return substr( $key, 0, 16);
        }
        return $key;
    }

    /**
     * 数据脱敏处理，只适用于加密数据且只取一条数据的情况--后续优化
     *
     * @return array|string
     */
    public static function dataDesensitization($data, $start = 3, $end = 4)
    {
        if (empty($data)){ return $data; }
        $words = Yii::$app->params['aesEncrypt']['words'];
        if (is_array($data) && !empty($data)) {
            $dataKeys = array_keys($data);
            $intersect = array_intersect($words, $dataKeys);
            if(empty($intersect)){
                return $data;
            }
            foreach($intersect as $k => $v){
                mb_strlen($data[$v]) > 7 && $data[$v] = self::strReplace((string)$data[$v], $start, $end);
            }
        }else{
            if (mb_strlen($data) > 7) {
                $data = self::strReplace((string)$data, $start, $end);
            }
        }
        return $data;
    }

    /**
     * 地址脱敏 - 固定格式
     * @return void
     */
    public static function addressDesen($data, $isAll = false)
    {
        if (empty($data)){ return $data; }
        $len = mb_strlen($data);
        if ($isAll) {
            $data = self::strReplace((string)$data, 0, 0);
        }else{
            if ($len <= 7) {
                $data = self::strReplace((string)$data, 0, 0);
            }elseif($len > 12) {
                $data = self::strReplace((string)$data, 9, 0);
            }elseif($len > 7 && $len <= 12){
                $data = self::strReplace((string)$data, 7, 0);
            }
        }

        return $data;
    }


    /**
     * 针对单值AES加解密
     * @param [type] $value
     * @param boolean $isEncrypt
     * @return
     */
    public static function sensitiveRowWords($value, $isEncrypt = true)
    {
        $key = Yii::$app->params['aesEncrypt']['key'];
        if ($isEncrypt) {
            return self::aesEncrypt($key, $value);
        }
        return self::aesDecrypt($key, $value);
    }

    /**
     * AES加解密
     *
     * @param array $data         加密原数据
     * @param boolean $isEncrypt  是否加密 true 加密  false 解密
     * @return void
     */
    public static function sensitiveWords($data, $isEncrypt = true)
    {
        $key = Yii::$app->params['aesEncrypt']['key'];
        $words = Yii::$app->params['aesEncrypt']['words'];
        $dataKeys = array_keys($data);
        $intersect = array_intersect($words, $dataKeys);
        if(empty($intersect)){
            return $data;
        }
        if ($isEncrypt) {
            foreach($intersect as $v) {
                $data[$v] = self::aesEncrypt($key, $data[$v]);
            }
        }else{
            foreach($intersect as $v) {
                $data[$v] = self::aesDecrypt($key, $data[$v]);
            }
        }
        return $data;
    }

    /**
     * 限制查询时间范围
     * @param $startTime
     * @param $endTime
     * @param $limitTime
     * @param string $msg
     * @return array
     */
    public static function limitQueryTimeRange($startTime, $endTime, $limitTime, $msg = '')
    {
        if (!$limitTime) {
            return static::toResult();
        }

        if (!$startTime) {
            $startTime = strtotime('2019-03-01 00:00:00');
        } elseif (!is_numeric($startTime)) {
            $startTime = strtotime($startTime);
        }

        if (!$endTime) {
            $endTime = time();
        } elseif (!is_numeric($endTime)) {
            $endTime = strtotime($endTime);
        }

        if (($endTime - $startTime) > $limitTime) {
            return static::toResult(-1, $msg ?: '超出查询范围，请缩小查询范围');
        }
    }

    /**
     * 是否在时间范围内
     * @param $startDateUnix
     * @param $endDateUnix
     * @return bool
     */
    public static function isTimeUp($startDateUnix, $endDateUnix)
    {
        $nowUnix = time();

        return $nowUnix >= $startDateUnix && $nowUnix <= $endDateUnix;
    }

    /**
     * JAVA文件转成PHP文件
     * @param $filePath
     * @return string
     */
    public static function javaImgToPhp($filePath)
    {
        if (!$filePath) {
            return '';
        }
        $res = Yii::$app->javaAliyunOss->getObject($filePath);
        if ($res['code'] || empty($res['data']['content'])) {
            Yii::error('获取文件信息失败：' . $filePath);
            return $filePath;
        }
        $content = $res['data']['content'];

        /*$res = Yii::$app->javaAliyunOss->getSignedUrl($filePath);
        if (empty($res['data']['url'])) {
            return $filePath;
        }
        $content = @file_get_contents($res['data']['url']);
        if (false === $content) {
            return $filePath;
        }*/
        $ext = pathinfo($filePath, PATHINFO_EXTENSION);
        $res = Yii::$app->aliyunOss->putObject('convert', $content, null, false, $ext ?: 'jpg');
        if ($res['code'] || empty($res['data']['object'])) {
            Yii::error('上传文件失败：' . $filePath);
            return $filePath;
        }

        return $res['data']['object'] ?? $filePath;
    }

    /**
     * PHP文件转成JAVA文件
     * @param $filePath
     * @return string
     */
    public static function phpImgToJava($filePath)
    {
        if (!$filePath) {
            return '';
        }
        $res = Yii::$app->aliyunOss->getObject($filePath);
        if ($res['code'] || empty($res['data']['content'])) {
            Yii::error('获取文件信息失败：' . $filePath);
            return $filePath;
        }
        $content = $res['data']['content'];
        $ext = pathinfo($filePath, PATHINFO_EXTENSION);
        $res = Yii::$app->javaAliyunOss->putObject(Yii::$app->params['javaAliyunUserCenterDir'], $content, null, false, $ext ?: 'jpg');
        if ($res['code'] || empty($res['data']['object'])) {
            Yii::error('上传文件失败：' . $filePath);
            return $filePath;
        }

        return $res['data']['object'] ?? $filePath;
    }

    /**
     * 相差的月份数量
     * @param $date1
     * @param $date2
     * @param string $tags
     * @return float|int
     * * @example:
    $date1 = "2003-08-11";
    $date2 = "2008-11-06";
    $monthNum = getMonthNum( $date1 , $date2 );
    echo $monthNum;
     */
    public static function getMonthNums($date1,$date2)
    {
        $date1 = date("Y-m-d", strtotime($date1));
        $date2 = date("Y-m-d", strtotime($date2));
        if (strtotime($date1) > strtotime($date2)) {
            $tmp = $date2;
            $date2 = $date1;
            $date1 = $tmp;
        }
        list($Y1, $m1, $d1) = explode('-', $date1);
        list($Y2, $m2, $d2) = explode('-', $date2);
        $y = $Y2 - $Y1;
        $m = $m2 - $m1;
        $d = $d2 - $d1;
        if ($d < 0) {
            $d += (int)date('t', strtotime("-1 month $date2"));
            $m--;
        }
        if ($m < 0) {
            $m += 12;
            $y--;
        }
        $mounth = $y * 12 + $m;
        return $mounth;
    }

    /**
     * 获取代码模块版本
     * @return int|mixed
     * @throws \yii\base\InvalidConfigException
     */
    public static function getCodeVersion()
    {
        $pathInfo = Yii::$app->request->getPathInfo();
        $pathInfo = explode('/', trim($pathInfo, '/'));
        $moduleVersion = reset($pathInfo);
        if (!preg_match('/^v(\d)+$/', $moduleVersion)) {
            $moduleVersion = Yii::$app->controller->module->id;
        }
        $moduleVersion = (int)str_replace('v', '', $moduleVersion);

        return $moduleVersion;
    }
}
